#include "Game.h"
#include "DXUtil.h"
#include <d3dx9.h>
#include <d3d9.h>
#include <iostream>
#include "ModelPrimitive.h"
#include "AnimChangeOverTime.h"
#include "Sphere.h"
#include "PhysicsPlane.h"


void Game::Initialize(LPDIRECT3DDEVICE9 d3ddev, LPDIRECT3D9 myDirect3D)
{
	mPhysWorld = new PhysicsWorld();
	mTotalTime = 0.0f;
	D3DXMatrixIdentity(&mIdentity);
	IniScene(d3ddev);
	LoadContent(d3ddev);
}

void Game::Update(LPDIRECT3DDEVICE9 d3ddev, double pElapsedTime) 
{
	mTotalTime += pElapsedTime;	
	if(tree->mKeyFrames.size() >0){
	if(tree->mKeyFrames.back()->GetTFinal() < mTotalTime){
				mTotalTime = 0;
	}
	}
	
	//bvh->Update(pElapsedTime);

	//mCamera->GetLookAt()->x = bvh->GetRoot()->GetFrames()->at(Node::mFrame)->at(0);
	//mCamera->GetLookAt()->y = bvh->GetRoot()->GetFrames()->at(Node::mFrame)->at(1);
	//mCamera->GetLookAt()->z = bvh->GetRoot()->GetFrames()->at(Node::mFrame)->at(2);
	if(tree->GetDone()){
		tree->Reset();
	}
	tree->Update(d3ddev,pElapsedTime,mTotalTime);

	for(int i = 0; i < mLights.size(); i++ )
	{
		if(mLights[i]->GetOn()){	
		    d3ddev->LightEnable(mLights[i]->GetLightNumber(), true);    // turn on light #0   
		}
		else if(mLights[i]->GetLightNumber() < 0 ){
			d3ddev->LightEnable(mLights[i]->GetLightNumber(),false);
		}
	}
}

D3DVECTOR* Game::DetermineEllipseTangent(D3DVECTOR* circle,D3DVECTOR* point )
{
     // This is just an implementation of the equation in the tutorial. All we need is a vector
     // giving the direction of the tangent, hence we only pay attention to the final terms.
 
     // The variable t is simply a parameter to the equation. We are only paying attention to
     // the final terms, and since they give the slope (i.e., the direction of the tangent), we
     // let t = 1.
 
   //  D3DVECTOR tangent = new D3DVECTOR();
    // tangent.x = point->x - (Ellipse->z* point->y)/Ellipse->z;
     //tangent.y = point->y + (Ellipse->z*point->x)/Ellipse->z;
	return NULL;
   //  return &tangent;     
}

void Game::IniScene(LPDIRECT3DDEVICE9 d3ddev){

	ModelPrimitive* tPrim = new ModelPrimitive();
	tPrim->SetBox(d3ddev,0.01,0.01,0.01,NULL);
		tPrim->GetMaterial()->Diffuse.r =1.0f;
		tPrim->GetMaterial()->Ambient.r = 1.0f;
		tPrim->GetMaterial()->Specular.r = 1.0f;
		tPrim->GetMaterial()->Emissive.r = 1.0f;
		
		tPrim->GetMaterial()->Diffuse.b =0.0f;
		tPrim->GetMaterial()->Ambient.b = 0.0f;
		tPrim->GetMaterial()->Specular.b = 0.0f;
		tPrim->GetMaterial()->Emissive.b = 0.0f;
		

	tree = new ParticleSystem();
	tree->GetMaterial()->Diffuse.r =1.0f;
	tree->GetMaterial()->Ambient.r = 1.0f;
	tree->GetMaterial()->Specular.r = 1.0f;
	tree->GetMaterial()->Emissive.r = 1.0f;
		
	tree->GetMaterial()->Diffuse.b =1.0f;
	tree->GetMaterial()->Ambient.b = 1.0f;
	tree->GetMaterial()->Specular.b =1.0f;
	tree->GetMaterial()->Emissive.b = 1.0f;

	tree->GetMaterial()->Diffuse.g =1.0f;
	tree->GetMaterial()->Ambient.g = 1.0f;
	tree->GetMaterial()->Specular.g = 1.0f;
	tree->GetMaterial()->Emissive.g = 1.0f;
	tree->SetSphere(d3ddev,0.1,10,10,NULL);

	tree->SetModel(tPrim);
	tree->SetPos(new D3DXVECTOR3(0,0,0));
	/*tree->AddKeyFrame(new KeyFrame(0,0,10,NULL,0,15000));	
	tree->AddKeyFrame(new KeyFrame(0,0,5,NULL,0,20000));	
	tree->AddKeyFrame(new KeyFrame(5,0,5,NULL,0,25000));	
	tree->AddKeyFrame(new KeyFrame(0,0,5,NULL,0,30000));	
	tree->AddKeyFrame(new KeyFrame(5,5,5,NULL,0,35000));	
	tree->AddKeyFrame(new KeyFrame(0,0,5,NULL,0,45000));*/	
	//tree->AddKeyFrame(new KeyFrame(10,10,00,NULL,0,30000));	
	
		

	mCamera = new Camera();

	D3DVIEWPORT9 view;
	d3ddev->GetViewport( &view);
	mCamera->SetAspectRatio(((float)(view.Width))/view.Height);
	
	mCamera->GetEyePos()->x = 0.0f;
	mCamera->GetEyePos()->y = 0.0f;
	mCamera->GetEyePos()->z = 10.0f;

	mCamera->SetLookAt(D3DXVECTOR3(0,0,0));

	mCamera->SetNearPlane(.0001f);

	mCamera->SetFarPlane(100000.0f);
	

	Light* mLight= new Light();

	/*mLight->GetDirection()->x = 0.0f;
	mLight->GetDirection()->y = 1.0f;
	mLight->GetDirection()->z = 0.0f;*/

	mLight->SetDirection(&D3DXVECTOR3(0,-1,-1));
	

	mLight->SetOn(true);
	mLights.push_back(mLight);

	for(int i = 0; i < mLights.size(); i++ )
	{
		mLights[i]->SetLightNumber(i);
		d3ddev->SetLight(mLights[i]->GetLightNumber()
						, mLight->GetD3DLight()); 
	}

	if(input.compare("") != 0)
	{
		float lifetime = 0.0f;
		float cosine = 0.0f;
		float radius = 0.0f;
		int genrate = 0;

		vector<KeyFrame> frames;

		ifstream fp_in;  // declarations of streams fp_in and fp_out
		fp_in.open(input.c_str(), ios::in);    // open the streams
		while(!fp_in.eof() && fp_in.good())
		{
			vector<string> tokens;
			string test;
			getline(fp_in, test);
			Tokenize(test, tokens);
			if(tokens[0].compare("radius") == 0)
			{
				radius = atof(tokens[1].c_str());
			}
			if(tokens[0].compare("cone_range") == 0)
			{
				cosine = 1.0f - atof(tokens[1].c_str());
			}
			if(tokens[0].compare("lifetime") == 0)
			{
				lifetime = atof(tokens[1].c_str());
			}
			if(tokens[0].compare("frame") == 0)
			{
				tree->AddKeyFrame(new KeyFrame(atof(tokens[1].c_str()),atof(tokens[2].c_str()),atof(tokens[3].c_str()),NULL,0,atof(tokens[4].c_str())));
			}
			if(tokens[0].compare("genrate") == 0)
			{
				genrate = atoi(tokens[1].c_str());
			}
		}

		fp_in.close();
		tree->Reset(radius, lifetime, cosine, genrate);
	}
}

void Game::LoadContent(LPDIRECT3DDEVICE9 d3ddev){


	for(int i = 0; i < mModels.size(); i++ )
	{
		//mModels[i]->LoadContent(d3ddev);
	}
}

//Draws the list of models
void Game::Draw(LPDIRECT3DDEVICE9 d3ddev){
	
	d3ddev->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0,0), 1.0f, 0); // clear frame
	d3ddev->BeginScene();

	//Set Camera
	d3ddev->SetTransform(D3DTS_VIEW, mCamera->GetViewMatrix());    // set the view transform to matView

    // set the projection transform
    d3ddev->SetTransform(D3DTS_PROJECTION, mCamera->GetProjectionMatrix());    // set the projection
	
	//mMesh->Draw(d3ddev);
	//Draw Models
	for(int i = 0; i < mModels.size(); i++ )
	{
		d3ddev->SetTransform(D3DTS_WORLD, &mIdentity);
		mModels[i]->Draw(d3ddev);
	}

//	for(int i = 0; i < bvh->GetOrder()->size(); i++ )
//	{
//		d3ddev->SetTransform(D3DTS_WORLD, &mIdentity);
//		bvh->GetOrder()->at(i)->Draw(d3ddev,NULL);
//	}
	
//	bvh->Draw(d3ddev,NULL);
	tree->Draw(d3ddev);
	
	d3ddev->EndScene();
}

void Game::Release(){

	for(int i = 0; i < mModels.size(); i++ )
	{
		mModels[i]->Release();
	}

}
